/****************************************************************/
//unit encompasses player and enemy. It has their stats and shared
//attributes.
// Tyler Wozniak & Andrew Hall
/***************************************************************/

#pragma once
//using namespace std;
//#include <string>
#include "imports.h"

class Unit
{
protected:
	int uHash; //Hash representing the unit
	int xPos, yPos; //It's x and y positions
	int health; //It's health
	int strength, agility, stamina; //The strength, agility and stamina stats
	string name; //The name of the unit
public:
	Unit(void);
	Unit(const Unit& u);
	Unit(int x, int y);
	//Unit operator=(const Unit& other); can't have a copy assignment operator for an abstract class
	static int unitCount;

	void playRandSound();
	int getX() const;
	int getY() const;
	int getStr() const;
	int getAgi() const;
	int getSta() const;
	int getHit() const;
	int getEva() const;
	int maxHealth() const;
	string getName() const;

	virtual void attack(Unit* other) = 0;
	virtual void moveW() = 0;
	virtual void moveE() = 0;
	virtual void moveN() = 0;
	virtual void moveS() = 0;
	virtual void moveNW() = 0;
	virtual void moveNE() = 0;
	virtual void moveSW() = 0;
	virtual void moveSE() = 0;
	int currentHealth() const;
	bool takeDamage(int amount);
	virtual operator char() const;
	bool operator==(const Unit& other) const;
	bool operator<(const Unit* other) const;

	//Got an error if I put this method in the CPP...not sure why
	inline friend ostream& operator<<(ostream& o, const Unit& u)
	{
		u.print(o);
		return o;
	}
	virtual void print(ostream& o) const;

	~Unit();
};

//Unit comparison functor
//Returns true if the first parameter is faster than the second
struct compareUnitEff
{
	bool operator()(Unit* first, Unit* second)
	{
		return (first->getAgi() > second->getAgi());
	}
};